/**
 * RedisUtil
 *
 * @author wangchen
 * @date 2024/6/9
 **/
package com.example.demo.util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Redis工具类（静态方法直接调用版）
 * 无需注入，直接通过 RedisUtil.xxx() 调用
 *
 * @author haochen78
 */
@Slf4j
@Component
public class RedisUtil {

    // 静态依赖变量（由Spring注入后赋值）
    private static StringRedisTemplate stringRedisTemplate;
    private static RedissonClient redissonClient;
    private static ObjectMapper objectMapper;

    // 实例变量（用于接收Spring注入）
    @Autowired
    private StringRedisTemplate instanceStringRedisTemplate;
    @Autowired
    private RedissonClient instanceRedissonClient;
    @Autowired
    private ObjectMapper instanceObjectMapper;

    // 初始化标记（确保依赖注入完成）
    private static boolean initialized = false;

    /**
     * 初始化方法，在Spring完成实例注入后执行
     * 将实例变量赋值给静态变量，供静态方法使用
     */
    @PostConstruct
    public void init() {
        try {
            // 将实例变量赋值给静态变量
            stringRedisTemplate = this.instanceStringRedisTemplate;
            redissonClient = this.instanceRedissonClient;
            objectMapper = this.instanceObjectMapper;

            // 配置ObjectMapper
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            initialized = true;
            log.info("RedisUtil初始化完成，静态方法可调用");
        } catch (Exception e) {
            log.error("RedisUtil初始化失败", e);
            throw new RuntimeException("RedisUtil初始化失败，请检查Spring容器依赖是否正确配置", e);
        }
    }

    /**
     * 校验工具类是否已初始化
     */
    private static void checkInitialized() {
        if (!initialized) {
            throw new IllegalStateException("RedisUtil尚未初始化，请检查Spring配置是否正确注入依赖");
        }
    }

    /**
     * 校验参数非空
     */
    private static void validateParam(boolean condition, String message) {
        if (!condition) {
            throw new IllegalArgumentException(message);
        }
    }

    /**
     * 校验key非空
     */
    private static void validateKey(String key) {
        validateParam(key != null && !key.trim().isEmpty(), "key不能为null或空字符串");
    }

    // =============================common============================

    /**
     * 指定缓存失效时间
     *
     * @param key  键（非null）
     * @param time 时间(秒)，<=0时不设置过期时间
     * @return 是否成功
     */
    public static boolean expire(String key, long time) {
        checkInitialized();
        validateKey(key);
        try {
            if (time > 0) {
                stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("设置过期时间失败 [key={}, time={}]", key, time, e);
            return false;
        }
    }

    /**
     * 获取key的过期时间
     *
     * @param key 键（非null）
     * @return 过期时间(秒)，-2表示key不存在，-1表示永久有效
     */
    public static long getExpire(String key) {
        checkInitialized();
        validateKey(key);
        try {
            Long expire = stringRedisTemplate.getExpire(key, TimeUnit.SECONDS);
            return expire != null ? expire : -2;
        } catch (Exception e) {
            log.error("获取过期时间失败 [key={}]", key, e);
            return -2;
        }
    }

    /**
     * 判断key是否存在
     *
     * @param key 键（非null）
     * @return true=存在，false=不存在
     */
    public static boolean hasKey(String key) {
        checkInitialized();
        validateKey(key);
        try {
            return Boolean.TRUE.equals(stringRedisTemplate.hasKey(key));
        } catch (Exception e) {
            log.error("判断key是否存在失败 [key={}]", key, e);
            return false;
        }
    }

    /**
     * 删除key
     *
     * @param key 键（非null）
     * @return true=删除成功
     */
    public static boolean delete(String key) {
        checkInitialized();
        validateKey(key);
        try {
            return Boolean.TRUE.equals(stringRedisTemplate.delete(key));
        } catch (Exception e) {
            log.error("删除key失败 [key={}]", key, e);
            return false;
        }
    }

    // ============================String=============================

    /**
     * 获取String类型值
     *
     * @param key 键（非null）
     * @return 值（可能为null）
     */
    public static String get(String key) {
        checkInitialized();
        validateKey(key);
        try {
            return stringRedisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            log.error("获取String值失败 [key={}]", key, e);
            return null;
        }
    }

    /**
     * 获取值并转换为指定类型
     *
     * @param key        键（非null）
     * @param targetType 目标类型（非null）
     * @return 转换后的对象（可能为null）
     */
    public static <T> T get(String key, Class<T> targetType) {
        checkInitialized();
        validateKey(key);
        validateParam(targetType != null, "targetType不能为null");

        String value = get(key);
        if (value == null) {
            return null;
        }

        try {
            return objectMapper.readValue(value, targetType);
        } catch (Exception e) {
            log.error("转换String值失败 [key={}, targetType={}]", key, targetType.getName(), e);
            return null;
        }
    }

    /**
     * 获取值并转换为复杂类型（如List、Map）
     *
     * @param key           键（非null）
     * @param typeReference 类型引用（非null，如new TypeReference<List<User>>(){}）
     * @return 转换后的对象（可能为null）
     */
    public static <T> T get(String key, TypeReference<T> typeReference) {
        checkInitialized();
        validateKey(key);
        validateParam(typeReference != null, "typeReference不能为null");

        String value = get(key);
        if (value == null) {
            return null;
        }

        try {
            return objectMapper.readValue(value, typeReference);
        } catch (Exception e) {
            log.error("转换复杂类型失败 [key={}, typeReference={}]", key, typeReference, e);
            return null;
        }
    }

    /**
     * 设置String类型值 永久有效
     *
     * @param key   键（非null）
     * @param value 值（允许为null，此时等同于删除key）
     * @return true=成功
     */
    public static boolean set(String key, String value) {
        checkInitialized();
        validateKey(key);
        try {
            stringRedisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            log.error("设置String值失败 [key={}, value={}]", key, value, e);
            return false;
        }
    }

    /**
     * 设置对象（自动序列化为JSON）
     *
     * @param key   键（非null）
     * @param value 对象（允许为null）
     * @return true=成功
     */
    public static boolean set(String key, Object value) {
        checkInitialized();
        validateKey(key);
        try {
            String jsonValue = objectMapper.writeValueAsString(value);
            return set(key, jsonValue);
        } catch (Exception e) {
            log.error("设置对象失败 [key={}, value={}]", key, value, e);
            return false;
        }
    }

    /**
     * 设置String值并指定过期时间
     *
     * @param key   键（非null）
     * @param value 值
     * @param time  过期时间(秒)，<=0时永久有效
     * @return true=成功
     */
    public static boolean set(String key, String value, long time) {
        checkInitialized();
        validateKey(key);
        try {
            if (time > 0) {
                stringRedisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            log.error("设置String值(带过期时间)失败 [key={}, value={}, time={}]", key, value, time, e);
            return false;
        }
    }

    /**
     * 设置对象并指定过期时间
     *
     * @param key   键（非null）
     * @param value 对象
     * @param time  过期时间(秒)
     * @return true=成功
     */
    public static boolean set(String key, Object value, long time) {
        checkInitialized();
        validateKey(key);
        try {
            String jsonValue = objectMapper.writeValueAsString(value);
            return set(key, jsonValue, time);
        } catch (Exception e) {
            log.error("设置对象(带过期时间)失败 [key={}, value={}, time={}]", key, value, time, e);
            return false;
        }
    }

    /**
     * 递增（分布式原子操作）
     *
     * @param key   键（非null）
     * @param delta 递增因子（必须>0）
     * @return 递增后的值
     */
    public static long incr(String key, long delta) {
        checkInitialized();
        validateKey(key);
        validateParam(delta > 0, "delta必须大于0");

        try {
            RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
            return atomicLong.addAndGet(delta);
        } catch (Exception e) {
            log.error("递增失败 [key={}, delta={}]", key, delta, e);
            return 0;
        }
    }

    /**
     * 递增并设置过期时间
     *
     * @param key        键（非null）
     * @param delta      递增因子（>0）
     * @param expireTime 过期时间(秒，>0)
     * @return 递增后的值
     */
    public static long incr(String key, long delta, long expireTime) {
        checkInitialized();
        validateKey(key);
        validateParam(delta > 0, "delta必须大于0");
        validateParam(expireTime > 0, "expireTime必须大于0");

        try {
            RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
            long newValue = atomicLong.addAndGet(delta);

            // 首次设置时添加过期时间
            if (newValue == delta) {
                atomicLong.expire(expireTime, TimeUnit.SECONDS);
            }
            return newValue;
        } catch (Exception e) {
            log.error("递增(带过期时间)失败 [key={}, delta={}, expireTime={}]", key, delta, expireTime, e);
            return 0;
        }
    }

    /**
     * 递减（分布式原子操作）
     *
     * @param key   键（非null）
     * @param delta 递减因子（必须>0）
     * @return 递减后的值
     */
    public static long decr(String key, long delta) {
        checkInitialized();
        validateKey(key);
        validateParam(delta > 0, "delta必须大于0");

        try {
            RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
            return atomicLong.addAndGet(-delta);
        } catch (Exception e) {
            log.error("递减失败 [key={}, delta={}]", key, delta, e);
            return 0;
        }
    }

    /**
     * 递减并设置过期时间
     *
     * @param key        键（非null）
     * @param delta      递减因子（>0）
     * @param expireTime 过期时间(秒，>0)
     * @return 递减后的值
     */
    public static long decr(String key, long delta, long expireTime) {
        checkInitialized();
        validateKey(key);
        validateParam(delta > 0, "delta必须大于0");
        validateParam(expireTime > 0, "expireTime必须大于0");

        try {
            RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
            long newValue = atomicLong.addAndGet(-delta);

            // 首次设置时添加过期时间
            if (newValue == -delta) {
                atomicLong.expire(expireTime, TimeUnit.SECONDS);
            }
            return newValue;
        } catch (Exception e) {
            log.error("递减(带过期时间)失败 [key={}, delta={}, expireTime={}]", key, delta, expireTime, e);
            return 0;
        }
    }

    // ================================Map=================================

    /**
     * 获取Hash表中的某个项
     *
     * @param key  键（非null）
     * @param item 项（非null）
     * @return 项的值（可能为null）
     */
    public static String hGet(String key, String item) {
        checkInitialized();
        validateKey(key);
        validateParam(item != null, "item不能为null");

        try {
            return (String) stringRedisTemplate.opsForHash().get(key, item);
        } catch (Exception e) {
            log.error("获取Hash项失败 [key={}, item={}]", key, item, e);
            return null;
        }
    }

    /**
     * 获取Hash表项并转换为指定类型
     *
     * @param key        键（非null）
     * @param item       项（非null）
     * @param targetType 目标类型（非null）
     * @return 转换后的对象（可能为null）
     */
    public static <T> T hGet(String key, String item, Class<T> targetType) {
        checkInitialized();
        validateKey(key);
        validateParam(item != null, "item不能为null");
        validateParam(targetType != null, "targetType不能为null");

        String value = hGet(key, item);
        if (value == null) {
            return null;
        }

        try {
            return objectMapper.readValue(value, targetType);
        } catch (Exception e) {
            log.error("转换Hash项失败 [key={}, item={}, targetType={}]", key, item, targetType.getName(), e);
            return null;
        }
    }

    /**
     * 获取Hash表中所有键值对
     *
     * @param key 键（非null）
     * @return 键值对集合（非null）
     */
    public static Map<Object, Object> hGetAll(String key) {
        checkInitialized();
        validateKey(key);
        try {
            return stringRedisTemplate.opsForHash().entries(key);
        } catch (Exception e) {
            log.error("获取Hash所有项失败 [key={}]", key, e);
            return Collections.emptyMap();
        }
    }

    /**
     * 获取Hash表所有项并转换为指定值类型
     *
     * @param key       键（非null）
     * @param valueType 值类型（非null）
     * @return 转换后的Map（非null）
     */
    public static <T> Map<String, T> hGetAll(String key, Class<T> valueType) {
        checkInitialized();
        validateKey(key);
        validateParam(valueType != null, "valueType不能为null");

        Map<Object, Object> entries = hGetAll(key);
        Map<String, T> result = new HashMap<>(entries.size());

        for (Map.Entry<Object, Object> entry : entries.entrySet()) {
            try {
                String itemKey = entry.getKey().toString();
                String jsonValue = (String) entry.getValue();
                T value = objectMapper.readValue(jsonValue, valueType);
                result.put(itemKey, value);
            } catch (ClassCastException e) {
                log.error("Hash项值不是字符串 [key={}, item={}]", key, entry.getKey(), e);
            } catch (Exception e) {
                log.error("转换Hash项值失败 [key={}, item={}]", key, entry.getKey(), e);
            }
        }
        return result;
    }

    /**
     * 批量设置Hash表项
     *
     * @param key 键（非null）
     * @param map 键值对（允许为null或空，此时返回true）
     * @return true=成功
     */
    public static boolean hSetAll(String key, Map<String, String> map) {
        checkInitialized();
        validateKey(key);
        if (map == null || map.isEmpty()) {
            return true;
        }

        try {
            stringRedisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            log.error("批量设置Hash项失败 [key={}, mapSize={}]", key, map.size(), e);
            return false;
        }
    }

    /**
     * 批量设置Hash表对象（自动序列化为JSON）
     *
     * @param key 键（非null）
     * @param map 对象集合（允许为null或空）
     * @return true=成功
     */
    public static boolean hSetAllObjects(String key, Map<String, Object> map) {
        checkInitialized();
        validateKey(key);
        if (map == null || map.isEmpty()) {
            return true;
        }

        try {
            Map<String, String> stringMap = new HashMap<>(map.size());
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                stringMap.put(entry.getKey(), objectMapper.writeValueAsString(entry.getValue()));
            }
            return hSetAll(key, stringMap);
        } catch (Exception e) {
            log.error("批量设置Hash对象失败 [key={}, mapSize={}]", key, map.size(), e);
            return false;
        }
    }

    /**
     * 批量设置Hash表项并指定过期时间
     *
     * @param key  键（非null）
     * @param map  键值对（允许为null或空）
     * @param time 过期时间(秒，>0时生效)
     * @return true=成功
     */
    public static boolean hSetAll(String key, Map<String, String> map, long time) {
        checkInitialized();
        validateKey(key);
        if (map == null || map.isEmpty()) {
            return true;
        }

        try {
            stringRedisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            log.error("批量设置Hash项(带过期时间)失败 [key={}, mapSize={}, time={}]", key, map.size(), time, e);
            return false;
        }
    }

    /**
     * 批量设置Hash表对象并指定过期时间
     *
     * @param key  键（非null）
     * @param map  对象集合（允许为null或空）
     * @param time 过期时间(秒)
     * @return true=成功
     */
    public static boolean hSetAllObjects(String key, Map<String, Object> map, long time) {
        checkInitialized();
        validateKey(key);
        if (map == null || map.isEmpty()) {
            return true;
        }

        try {
            Map<String, String> stringMap = new HashMap<>(map.size());
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                stringMap.put(entry.getKey(), objectMapper.writeValueAsString(entry.getValue()));
            }
            return hSetAll(key, stringMap, time);
        } catch (Exception e) {
            log.error("批量设置Hash对象(带过期时间)失败 [key={}, mapSize={}, time={}]", key, map.size(), time, e);
            return false;
        }
    }

    /**
     * 设置Hash表中的某个项
     *
     * @param key   键（非null）
     * @param item  项（非null）
     * @param value 值（允许为null）
     * @return true=成功
     */
    public static boolean hSet(String key, String item, String value) {
        checkInitialized();
        validateKey(key);
        validateParam(item != null, "item不能为null");

        try {
            stringRedisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            log.error("设置Hash项失败 [key={}, item={}, value={}]", key, item, value, e);
            return false;
        }
    }

    /**
     * 设置Hash表中的对象项（自动序列化为JSON）
     *
     * @param key   键（非null）
     * @param item  项（非null）
     * @param value 对象（允许为null）
     * @return true=成功
     */
    public static boolean hSet(String key, String item, Object value) {
        checkInitialized();
        validateKey(key);
        validateParam(item != null, "item不能为null");

        try {
            String jsonValue = objectMapper.writeValueAsString(value);
            return hSet(key, item, jsonValue);
        } catch (Exception e) {
            log.error("设置Hash对象项失败 [key={}, item={}, value={}]", key, item, value, e);
            return false;
        }
    }

    /**
     * 设置Hash表项并指定过期时间
     *
     * @param key   键（非null）
     * @param item  项（非null）
     * @param value 值
     * @param time  过期时间(秒，>0时生效)
     * @return true=成功
     */
    public static boolean hSet(String key, String item, String value, long time) {
        checkInitialized();
        validateKey(key);
        validateParam(item != null, "item不能为null");

        try {
            stringRedisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            log.error("设置Hash项(带过期时间)失败 [key={}, item={}, value={}, time={}]", key, item, value, time, e);
            return false;
        }
    }

    /**
     * 设置Hash表对象项并指定过期时间
     *
     * @param key   键（非null）
     * @param item  项（非null）
     * @param value 对象
     * @param time  过期时间(秒)
     * @return true=成功
     */
    public static boolean hSet(String key, String item, Object value, long time) {
        checkInitialized();
        validateKey(key);
        validateParam(item != null, "item不能为null");

        try {
            String jsonValue = objectMapper.writeValueAsString(value);
            return hSet(key, item, jsonValue, time);
        } catch (Exception e) {
            log.error("设置Hash对象项(带过期时间)失败 [key={}, item={}, value={}, time={}]", key, item, value, time, e);
            return false;
        }
    }

    /**
     * 删除Hash表中的项
     *
     * @param key  键（非null）
     * @param item 项（至少一个，非null）
     */
    public static void hDelete(String key, Object... item) {
        checkInitialized();
        validateKey(key);
        validateParam(item != null && item.length > 0, "item不能为null或空");

        try {
            stringRedisTemplate.opsForHash().delete(key, item);
        } catch (Exception e) {
            log.error("删除Hash项失败 [key={}, items={}]", key, Arrays.toString(item), e);
        }
    }

    /**
     * 判断Hash表中是否存在某个项
     *
     * @param key  键（非null）
     * @param item 项（非null）
     * @return true=存在
     */
    public static boolean hHasKey(String key, String item) {
        checkInitialized();
        validateKey(key);
        validateParam(item != null, "item不能为null");

        try {
            return stringRedisTemplate.opsForHash().hasKey(key, item);
        } catch (Exception e) {
            log.error("判断Hash项是否存在失败 [key={}, item={}]", key, item, e);
            return false;
        }
    }

    // ============================Set=============================

    /**
     * 获取Set中的所有元素
     *
     * @param key 键（非null）
     * @return 元素集合（非null）
     */
    public static Set<String> sGet(String key) {
        checkInitialized();
        validateKey(key);
        try {
            return stringRedisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            log.error("获取Set元素失败 [key={}]", key, e);
            return Collections.emptySet();
        }
    }

    /**
     * 判断Set中是否包含某个元素
     *
     * @param key   键（非null）
     * @param value 元素（非null）
     * @return true=包含
     */
    public static boolean sContains(String key, Object value) {
        checkInitialized();
        validateKey(key);
        validateParam(value != null, "value不能为null");

        try {
            return Boolean.TRUE.equals(stringRedisTemplate.opsForSet().isMember(key, value));
        } catch (Exception e) {
            log.error("判断Set包含元素失败 [key={}, value={}]", key, value, e);
            return false;
        }
    }

    /**
     * 向Set中添加元素
     *
     * @param key    键（非null）
     * @param values 元素（至少一个，非null）
     * @return 成功添加的数量
     */
    public static long sAdd(String key, String... values) {
        checkInitialized();
        validateKey(key);
        validateParam(values != null && values.length > 0, "values不能为null或空");

        try {
            Long add = stringRedisTemplate.opsForSet().add(key, values);
            return add != null ? add : 0;
        } catch (Exception e) {
            log.error("添加Set元素失败 [key={}, valuesSize={}]", key, values.length, e);
            return 0;
        }
    }

    /**
     * 向Set中添加元素并设置过期时间
     *
     * @param key    键（非null）
     * @param time   过期时间(秒，>0)
     * @param values 元素（至少一个，非null）
     * @return 成功添加的数量
     */
    public static long sAddWithTime(String key, long time, String... values) {
        checkInitialized();
        validateKey(key);
        validateParam(time > 0, "time必须大于0");
        validateParam(values != null && values.length > 0, "values不能为null或空");

        try {
            Long count = stringRedisTemplate.opsForSet().add(key, values);
            expire(key, time);
            return count != null ? count : 0;
        } catch (Exception e) {
            log.error("添加Set元素(带过期时间)失败 [key={}, time={}, valuesSize={}]", key, time, values.length, e);
            return 0;
        }
    }

    /**
     * 获取Set的大小
     *
     * @param key 键（非null）
     * @return 元素数量
     */
    public static long sSize(String key) {
        checkInitialized();
        validateKey(key);
        try {
            Long size = stringRedisTemplate.opsForSet().size(key);
            return size != null ? size : 0;
        } catch (Exception e) {
            log.error("获取Set大小失败 [key={}]", key, e);
            return 0;
        }
    }

    /**
     * 从Set中移除元素
     *
     * @param key    键（非null）
     * @param values 元素（至少一个，非null）
     * @return 移除的数量
     */
    public static long sRemove(String key, Object... values) {
        checkInitialized();
        validateKey(key);
        validateParam(values != null && values.length > 0, "values不能为null或空");

        try {
            Long remove = stringRedisTemplate.opsForSet().remove(key, values);
            return remove != null ? remove : 0;
        } catch (Exception e) {
            log.error("移除Set元素失败 [key={}, values={}]", key, Arrays.toString(values), e);
            return 0;
        }
    }

    // ===============================List=================================

    /**
     * 获取List中指定范围的元素
     *
     * @param key   键（非null）
     * @param start 开始索引（0为第一个元素）
     * @param end   结束索引（-1为最后一个元素）
     * @return 元素列表（非null）
     */
    public static List<String> lGet(String key, long start, long end) {
        checkInitialized();
        validateKey(key);
        try {
            return stringRedisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            log.error("获取List范围元素失败 [key={}, start={}, end={}]", key, start, end, e);
            return Collections.emptyList();
        }
    }

    /**
     * 获取List的长度
     *
     * @param key 键（非null）
     * @return 长度
     */
    public static long lSize(String key) {
        checkInitialized();
        validateKey(key);
        try {
            Long size = stringRedisTemplate.opsForList().size(key);
            return size != null ? size : 0;
        } catch (Exception e) {
            log.error("获取List长度失败 [key={}]", key, e);
            return 0;
        }
    }

    /**
     * 获取List中指定索引的元素
     *
     * @param key   键（非null）
     * @param index 索引（正数从左，负数从右：-1为最后一个）
     * @return 元素（可能为null）
     */
    public static String lGetIndex(String key, long index) {
        checkInitialized();
        validateKey(key);
        try {
            return stringRedisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            log.error("获取List指定索引元素失败 [key={}, index={}]", key, index, e);
            return null;
        }
    }

    /**
     * 向List尾部添加元素
     *
     * @param key   键（非null）
     * @param value 值（非null）
     * @return true=成功
     */
    public static boolean lAdd(String key, String value) {
        checkInitialized();
        validateKey(key);
        validateParam(value != null, "value不能为null");
        try {
            stringRedisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            log.error("向List添加元素失败 [key={}, value={}]", key, value, e);
            return false;
        }
    }

    /**
     * 向List尾部添加元素并设置过期时间
     *
     * @param key   键（非null）
     * @param value 值（非null）
     * @param time  过期时间(秒，>0)
     * @return true=成功
     */
    public static boolean lAdd(String key, String value, long time) {
        checkInitialized();
        validateKey(key);
        validateParam(value != null, "value不能为null");
        validateParam(time > 0, "time必须大于0");

        try {
            stringRedisTemplate.opsForList().rightPush(key, value);
            expire(key, time);
            return true;
        } catch (Exception e) {
            log.error("向List添加元素(带过期时间)失败 [key={}, value={}, time={}]", key, value, time, e);
            return false;
        }
    }

    /**
     * 向List尾部批量添加元素
     *
     * @param key    键（非null）
     * @param values 元素列表（非null且至少一个元素）
     * @return true=成功
     */
    public static boolean lAddAll(String key, List<String> values) {
        checkInitialized();
        validateKey(key);
        validateParam(values != null && !values.isEmpty(), "values不能为null或空");

        try {
            stringRedisTemplate.opsForList().rightPushAll(key, values);
            return true;
        } catch (Exception e) {
            log.error("向List批量添加元素失败 [key={}, valuesSize={}]", key, values.size(), e);
            return false;
        }
    }

    /**
     * 向List尾部批量添加元素并设置过期时间
     *
     * @param key    键（非null）
     * @param values 元素列表（非null且至少一个元素）
     * @param time   过期时间(秒，>0)
     * @return true=成功
     */
    public static boolean lAddAll(String key, List<String> values, long time) {
        checkInitialized();
        validateKey(key);
        validateParam(values != null && !values.isEmpty(), "values不能为null或空");
        validateParam(time > 0, "time必须大于0");

        try {
            stringRedisTemplate.opsForList().rightPushAll(key, values);
            expire(key, time);
            return true;
        } catch (Exception e) {
            log.error("向List批量添加元素(带过期时间)失败 [key={}, valuesSize={}, time={}]", key, values.size(), time, e);
            return false;
        }
    }

    /**
     * 更新List中指定索引的元素
     *
     * @param key   键（非null）
     * @param index 索引
     * @param value 新值（非null）
     * @return true=成功
     */
    public static boolean lUpdateIndex(String key, long index, String value) {
        checkInitialized();
        validateKey(key);
        validateParam(value != null, "value不能为null");
        try {
            stringRedisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            log.error("更新List指定索引元素失败 [key={}, index={}, value={}]", key, index, value, e);
            return false;
        }
    }

    /**
     * 从List中删除指定元素
     *
     * @param key   键（非null）
     * @param count 删除数量（正数从左，负数从右）
     * @param value 要删除的元素（非null）
     * @return 实际删除的数量
     */
    public static long lRemove(String key, long count, Object value) {
        checkInitialized();
        validateKey(key);
        validateParam(value != null, "value不能为null");
        try {
            Long remove = stringRedisTemplate.opsForList().remove(key, count, value);
            return remove != null ? remove : 0;
        } catch (Exception e) {
            log.error("删除List元素失败 [key={}, count={}, value={}]", key, count, value, e);
            return 0;
        }
    }

    // ============================分布式锁=============================

    /**
     * 尝试获取分布式锁
     *
     * @param key       锁的键（非null）
     * @param waitTime  等待时间(秒)
     * @param leaseTime 自动释放时间(秒)
     * @return 是否获取成功
     */
    public static boolean tryLock(String key, long waitTime, long leaseTime) {
        checkInitialized();
        validateKey(key);
        validateParam(waitTime >= 0, "waitTime不能为负数");
        validateParam(leaseTime > 0, "leaseTime必须大于0");

        try {
            return redissonClient.getLock(key).tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.error("尝试获取分布式锁失败 [key={}, waitTime={}, leaseTime={}]", key, waitTime, leaseTime, e);
            return false;
        }
    }

    /**
     * 释放分布式锁
     *
     * @param key 锁的键（非null）
     */
    public static void unlock(String key) {
        checkInitialized();
        validateKey(key);
        try {
            redissonClient.getLock(key).unlock();
        } catch (Exception e) {
            log.error("释放分布式锁失败 [key={}]", key, e);
        }
    }
}
